package com.canin.member.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.canin.Constant;
import com.canin.dao.BedDAO;
import com.canin.dao.BowlDAO;
import com.canin.dao.CollarDAO;
import com.canin.dao.DAOFactory;
import com.canin.dao.DogDAO;
import com.canin.dao.FoodDAO;
import com.canin.dao.KennelDAO;
import com.canin.dao.LeashDAO;
import com.canin.dao.SizeDAO;
import com.canin.dao.ToothbrushDAO;
import com.canin.model.Bed;
import com.canin.model.Bowl;
import com.canin.model.Collar;
import com.canin.model.Dog;
import com.canin.model.Food;
import com.canin.model.FoodFTN;
import com.canin.model.FoodProduct;
import com.canin.model.Kennel;
import com.canin.model.Leash;
import com.canin.model.Member;
import com.canin.model.Size;
import com.canin.model.Suggest;
import com.canin.model.Tool;
import com.canin.model.Toothbrush;
import com.canin.util.CaninUtil;
import com.opensymphony.xwork2.ActionSupport;

public class SuggAction extends ActionSupport implements SessionAware
{
	private static final long serialVersionUID = 1486003668139713989L;
	
	private Map<String, Object> userSession;
	private Member member = new Member();
	private Dog dog = new Dog();
	
	private Suggest suggForm = new Suggest();
	private Suggest sugg = new Suggest();

	private Map<String, String> dogNameList = null;
	private Map<String, String> sizes = null;
	
	private List<Food> desireFoodList = null;
	private List<Tool> desireToolList = null;
	
	private String foodDetailIndex;
	private String foodDetailAmount;
	private Food selectedFood;
	
	public String food() throws Exception
	{
		initialValue();
		
		return "food";
	}
	
	public String tool() throws Exception
	{
		initialValue();
		
		return "tool";
	}
	
	public String dogT() throws Exception
	{
		initialValue();
		
		DAOFactory daoFactory = new DAOFactory();
		daoFactory.beginConnection();
		DogDAO dogDAO = daoFactory.createDogDAO();
		
		if ( !"-1".equals(suggForm.getDogNameList() ) )
		{
			suggForm.setShowLastUpdated(true);
			
			suggForm.setDogName( dogNameList.get( suggForm.getDogNameList() ) );
			dog = dogDAO.getDogStaticById( member.getMemberId(), Integer.parseInt(suggForm.getDogNameList()) );
			dog = dogDAO.getDogDynamicById( dog );
			
			suggForm.setDateCount( CaninUtil.generateDateCount( dog.getUpdatedDate() ) );
			
			userSession.put(Constant.DOG, dog);
			userSession.put(Constant.SUGG, suggForm);
		}
		else
		{
			suggForm.setShowLastUpdated(false);
			suggForm.setShowDetail(false);
		}
		
		return "tool";
	}
	
	public String dog() throws Exception
	{
		initialValue();
		
		DAOFactory daoFactory = new DAOFactory();
		daoFactory.beginConnection();
		DogDAO dogDAO = daoFactory.createDogDAO();
		
		if ( !"-1".equals(suggForm.getDogNameList() ) )
		{
			suggForm.setShowLastUpdated(true);
			
			suggForm.setDogName( dogNameList.get( suggForm.getDogNameList() ) );
			dog = dogDAO.getDogStaticById( member.getMemberId(), Integer.parseInt(suggForm.getDogNameList()) );
			dog = dogDAO.getDogDynamicById( dog );
			
			suggForm.setDateCount( CaninUtil.generateDateCount( dog.getUpdatedDate() ) );
			
			userSession.put(Constant.DOG, dog);
			userSession.put(Constant.SUGG, suggForm);
		}
		else
		{
			suggForm.setShowLastUpdated(false);
			suggForm.setShowDetail(false);
		}
		
		return "food";
	}
	
	public String calc() throws Exception
	{
		initialValue();
		showDetail();
		
		// Predefine PeriodDay
//		suggForm.setPeriodDay( getRemainDayInPeriod( dog.getPregnantWeeks(), dog.getLactateWeeks() ) );
//		getRemainDayInPeriod( dog.getPregnantWeeks(), dog.getLactateWeeks() );
		
		return "food";
	}
	
	public String show() throws Exception
	{
		initialValue();
		showDetail();
		
		return "tool";
	}
	
	public String searchT() throws Exception
	{
		initialValue();
		
		boolean selectedBed = suggForm.isBed();
		boolean selectedBowl = suggForm.isBowl();
		boolean selectedKennel = suggForm.isKennel();
		boolean selectedLeash = suggForm.isLeash();
		boolean selectedToothbrush = suggForm.isToothbrush();
		boolean selectedCollar = suggForm.isCollar();
		
		// reset NOT_FOUND_FLAG
//		suggForm.setFoundBed( Constant.FOUND );
//	    suggForm.setFoundBed( Constant.FOUND );
//	    suggForm.setFoundBowl( Constant.FOUND );
//	    suggForm.setFoundLeash( Constant.FOUND );
//	    suggForm.setFoundKennel( Constant.FOUND );
//	    suggForm.setFoundToothbrush( Constant.FOUND );
//	    suggForm.setFoundCollar( Constant.FOUND );
		
		showDetail();
		
		dog = (Dog)userSession.get( Constant.DOG );
		String calDogSize = getDogSize( suggForm.getBreedSize(), dog.getYearOfBirth(), dog.getMonthOfBirth() );
		
		desireToolList = new ArrayList<Tool>();

		// covert DogSize to ToolSize
		String toolSize = convertDogSizeToolSize( calDogSize );
		DAOFactory daoFactory = new DAOFactory();
		daoFactory.beginConnection();
		if ( selectedBed )
		{
			// Get Bed By Size
			BedDAO bedDAO = daoFactory.createBedDAO();
			ArrayList<Bed> desiredBed = bedDAO.getBedBySize( toolSize );
			
			if ( desiredBed.size() == 0 ){
				suggForm.setFoundBed( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundBed( Constant.FOUND );
			}
			desireToolList.addAll( desiredBed );
		}
		else
		{
			suggForm.setFoundBed( "" );
		}
		
		ArrayList<Bowl> desiredBowl;
		if ( selectedBowl )
		{
			// Get Bed By Size
			BowlDAO bowlDAO = daoFactory.createBowlDAO();
			desiredBowl = bowlDAO.getBowlBySize( toolSize );
			
			if ( desiredBowl.size() == 0 ){
				suggForm.setFoundBowl( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundBowl( Constant.FOUND );
			}
			
			for ( Bowl bowl: desiredBowl )
			{
				desireToolList.add( bowl );
			}
		}
		else
		{
			suggForm.setFoundBowl( "" );
		}
		
		ArrayList<Kennel> desiredKennel;
		if ( selectedKennel )
		{
			// Get Bed By Size
			KennelDAO kennelDAO = daoFactory.createKennelDAO();
			desiredKennel = kennelDAO.getKennelBySize( toolSize );
			
			if ( desiredKennel.size() == 0 ){
				suggForm.setFoundKennel( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundKennel( Constant.FOUND );
			}
			
			for ( Kennel kennel: desiredKennel )
			{
				desireToolList.add( kennel );
			}
		}
		else
		{
			suggForm.setFoundKennel( "" );
		}
		
		ArrayList<Leash> desiredLeash;
		if ( selectedLeash )
		{
			// Get Bed By Size
			LeashDAO leashDAO = daoFactory.createLeashDAO();
			desiredLeash = leashDAO.getLeashBySize( toolSize );
			
			if ( desiredLeash.size() == 0 ){
				suggForm.setFoundLeash( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundLeash( Constant.FOUND );
			}
			
			for ( Leash leash: desiredLeash )
			{
				desireToolList.add( leash );
			}
		}
		else
		{
			suggForm.setFoundLeash( "" );
		}
		
		ArrayList<Toothbrush> desiredToothbrush;
		if ( selectedToothbrush )
		{
			// Get Bed By Size
			ToothbrushDAO toothbrushDAO = daoFactory.createToothbrushDAO();
			desiredToothbrush = toothbrushDAO.getToothbrushBySize( toolSize );
			
			if ( desiredToothbrush.size() == 0 ){
				suggForm.setFoundToothbrush( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundToothbrush( Constant.FOUND );
			}
			
			for ( Toothbrush toothbrush: desiredToothbrush )
			{
				desireToolList.add( toothbrush );
			}
		}
		else
		{
			suggForm.setFoundToothbrush( "" );
		}
		
		
		ArrayList<Collar> desiredCollar;
		if ( selectedCollar )
		{
			// Get Bed By Size
			CollarDAO collarDAO = daoFactory.createCollarDAO();
			desiredCollar = collarDAO.getCollarBySize( toolSize );
			
			if ( desiredCollar.size() == 0 ){
				suggForm.setFoundCollar( Constant.NOT_FOUND );
			}else{
				suggForm.setFoundCollar( Constant.FOUND );
			}
			
			for ( Collar collar: desiredCollar )
			{
				desireToolList.add( collar );
			}
		}
		else
		{
			suggForm.setFoundCollar( "" );
		}
		
		suggForm.setBed( selectedBed );
		suggForm.setBowl( selectedBowl );
		suggForm.setKennel( selectedKennel );
		suggForm.setLeash( selectedLeash );
		suggForm.setToothbrush( selectedToothbrush );
		suggForm.setCollar( selectedCollar );
		
		userSession.put(Constant.SUGG, suggForm);

		userSession.put(Constant.ORDER_TOOL, desireToolList);
		
		return "tool";
	}
	
	public String search() throws Exception
	{
		initialValue();
		dog = (Dog)userSession.get( Constant.DOG );
//		ArrayList<FoodProduct> fixbug = new ArrayList<FoodProduct>();
		
		if ( "F".equalsIgnoreCase(dog.getSex())
			&& ( dog.getPregnantWeeks() > 0 || dog.getLactateWeeks() > 0 )
			&& suggForm.getPeriodDay() > getRemainDayInPeriod( dog.getPregnantWeeks(), dog.getLactateWeeks() ) )
		{
			addActionMessage("จำนวนวันที่ระบุ เกินกว่าวันที่แม่สุนัขจะคลอดลูก หรือลูกสุนัขในครอกหย่านม");
		}
		else if ( suggForm.isWetFoodType() 
			&& !suggForm.isDryFoodType()
			&& suggForm.getPeriodDay() > 21 )
		{
			addActionMessage("อาหารเปียก ไม่ควรซื้อเกิน 3 สัปดาห์ (21) วัน");
		}
		else
		{
			// Choose the proper food
//			addActionMessage("Ready to Suggest!!");
			DAOFactory daoFactory = new DAOFactory();
			daoFactory.beginConnection();
			FoodDAO foodDAO = daoFactory.createFoodDAO();
			ArrayList<Food> foodList = foodDAO.getAllFood();
			
			// Remove un-desire food
			ArrayList<Food> toRemoveFoodList = new ArrayList<Food>();
			toRemoveFoodList.addAll(foodList);
			
			// Dog Value ( calc before loop to compare )
			sugg = (Suggest)userSession.get( Constant.SUGG );
			String dogLifeSpan = CaninUtil.changeLifeSpanThaiToEng( sugg.getLifeSpan() );
			String dogSize = CaninUtil.getBreedSizeByBreedId( dog.getBreedId() );
			
			for ( Food food : foodList )
			{
				// 1. Remove food that have ingredient Dog Allergy
				if (dog.getAllergyToBeef() == 1 && food.getBeefIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToChicken() == 1 && food.getChickenIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToCorn() == 1 && food.getCornIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToEgg() == 1 && food.getEggIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToFish() == 1 && food.getFishIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToMilk() == 1 && food.getMilkIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToPork() == 1 && food.getPorkIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToSoybean() == 1 && food.getSoybeanIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				else if (dog.getAllergyToWhey() == 1 && food.getWheyIngredient() == 1)
				{
					toRemoveFoodList.remove(food);
				}
				
				// 2. Same Age
				boolean sameLifeSpan = false;
				if ( "".equals( food.getDogAge() ) )
				{
					food.setAgeFlag( false );
					sameLifeSpan = true;
				}
				else if ( dogLifeSpan.equalsIgnoreCase( food.getDogAge() ) )
				{
					food.setAgeFlag( true );
					sameLifeSpan = true;
				}
				
				if ( !sameLifeSpan )
				{
					toRemoveFoodList.remove( food );
				}
				
				// 3. Same Size or Breed
				boolean sameSize = false;
				if ( "".equals(food.getDogSize()) || Constant.SIZE_ALL.equals( food.getDogSize() ) )
				{
					food.setSizeFlag( false );
					sameSize = true;
				}
				else if ( food.getDogSize().equalsIgnoreCase( dogSize ) )
				{
					food.setSizeFlag( true );
					sameSize = true;
				}
				
				boolean sameBreed = false;
				if ( food.getDogBreedId() == 0 )
				{
					food.setBreedFlag( false );
					sameBreed = true;
				}
				else if ( food.getDogBreedId() == dog.getBreedId() )
				{
					food.setBreedFlag( true );
					sameBreed = true;
				}
				
				if ( !sameSize || !sameBreed )
				{
					toRemoveFoodList.remove( food );
				}
			}
			
			// Copy all remain food
			foodList = new ArrayList<Food>();
			foodList.addAll(toRemoveFoodList);
			ArrayList<Food> remainFoodList = new ArrayList<Food>();
			
			// User Value ( calc before loop to compare )
			boolean isSpecifyFoodFTN = isSpecifyFoodFTN( suggForm );
			boolean isSpecifyFoodType = isSpecifyFoodType( suggForm );
			for ( Food food : foodList )
			{
				// 4. Same Food Nutrition
				boolean sameFoodFTN = false;
				if ( isSpecifyFoodFTN )
				{
					if ( isContainFoodFTNType( food.getId(), suggForm ) )
					{
						food.setFtnFlag( false );
						sameFoodFTN = true;
					}
				}
				else
				{
					food.setFtnFlag( true );
					sameFoodFTN = true;
				}
				
				// 5. Same Food Type (Dry/Wet)
				boolean sameFoodType = false;
				if ( isSpecifyFoodType )
				{
					if ( suggForm.isWetFoodType() && "Wet".equalsIgnoreCase(food.getFoodType()) )
					{
						sameFoodType = true;
					}
					else if ( suggForm.isDryFoodType() && "Dry".equalsIgnoreCase(food.getFoodType()) )
					{
						sameFoodType = true;
					}
					food.setTypeFlag( true );
				}
				else
				{
					food.setTypeFlag( false );
					sameFoodType = true;
				}
				
				// Add desire Food
				if ( sameFoodFTN && sameFoodType )
				{
					remainFoodList.add( food );
				}
			}
			
			// Calc before loop to compare
			Double dogCalloriesPerDay = CaninUtil.calcDogCalloriesPerDay( dogLifeSpan, dog );
			dog.setCalloriesPerDay( dogCalloriesPerDay );
			
			desireFoodList = new ArrayList<Food>();
			int index = 0;
			for( Food food : remainFoodList )
			{
				ArrayList<FoodProduct> foodProductList = foodDAO.getSizeAndPrice( food.getId() );
				for ( FoodProduct foodProduct : foodProductList )
				{
					double dayCount = CaninUtil.round2decimal((food.getKilocalorie()*foodProduct.getSizeKg())/dogCalloriesPerDay);
					
					// Add FoodProduct, only if 
					// - price IS NOT OVER budget
					// - dayCount IS OVER user's periodDay
					if ( ( suggForm.getBudget() == 0 || foodProduct.getPrice() < suggForm.getBudget() )
						&& ( suggForm.getPeriodDay() == 0 || dayCount > suggForm.getPeriodDay() ) )
					{
//						addActionMessage( food.getId() + " : " + foodProduct.getSizeKg() );
						double pricePerKilogram = CaninUtil.round2decimal( foodProduct.getPrice()/foodProduct.getSizeKg() );
						double pricePerDay = CaninUtil.round2decimal( foodProduct.getPrice()/dayCount );
						
						foodProduct.setPricePerKilogram( pricePerKilogram );
						foodProduct.setFeedDayCount( (int)dayCount );
						foodProduct.setPricePerDay( pricePerDay );
						
						food.setSizeKg( foodProduct.getSizeKg() );
//						food.setSizeKg( index );
						food.setPrice( foodProduct.getPrice() );
						food.setPricePerKilogram( foodProduct.getPricePerKilogram() );
						food.setFeedDayCount( foodProduct.getFeedDayCount() );
						food.setPricePerDay( foodProduct.getPricePerDay() );
						
						food.setFoodFTNList( getFoodFTNList( food.getId() ) );
						
//						addActionMessage( food.getId() + " - " + food.getSizeKg() );
						desireFoodList.add(food);
						index++;
					}
				}
			}
		}
		
		desireFoodList = removeFoodDuplicate( desireFoodList );
//		desireFoodList = mergeWithSizeAndPrice( desireFoodList, fixbug );
		
		// Calculate for Diet Week
		if ( suggForm.isDietFlag() )
		{
			int dietWeek = CaninUtil.getWeekToDiet( (double)dog.getDogWeight(), (double)suggForm.getIdealWeight() );
			addActionMessage( "จำนวนวันที่แนะนำ เพื่อให้สุนัขลดน้ำหนักได้ตามที่ต้องการคือ " + (dietWeek*7) + " วัน หรือ " + dietWeek + " สัปดาห์" );
		}
		
		sugg = (Suggest)userSession.get( Constant.SUGG );
		suggForm = MergeSuggFormIntoSugg( suggForm, sugg );
		
		userSession.put(Constant.DOG, dog);
		userSession.put(Constant.ORDER_FOOD, desireFoodList);
		
		return "food";
	}
	
	@SuppressWarnings("unchecked")
	public String orderFood() throws Exception
	{
		String returnString = "";
		
		if ( isOrderSome( desireFoodList ) )
		{
			// merge amount into desireFoodList;
			List<Food> amountFoodList = desireFoodList;
			desireFoodList = (List<Food>)userSession.get( Constant.ORDER_FOOD );
			
			ArrayList<Food> orderFoodList = new ArrayList<Food>();
			orderFoodList = mergeAmountIntoDesireFoodList( desireFoodList, amountFoodList );
			userSession.put(Constant.ORDER_FOOD, orderFoodList);
			
			// Go to order screen
			returnString = "orderFood";
		}
		else
		{
			initialValue();
			suggForm = (Suggest)userSession.get( Constant.SUGG );
			desireFoodList = (List<Food>)userSession.get( Constant.ORDER_FOOD );
			addActionMessage( "กรุณาระบุจำนวนผลิตภัณฑ์อาหารที่ท่านต้องการ" );
			
			returnString = "food";
		}
		
		return returnString;
	}
	
	@SuppressWarnings("unchecked")
	public String orderTool() throws Exception
	{
		String returnString = "";
		
		if ( isOrderSomeT( desireToolList ) )
		{
			// merge amount into desireToolList;
			List<Tool> amountToolList = desireToolList;
			desireToolList = (List<Tool>)userSession.get( Constant.ORDER_TOOL );
			
			ArrayList<Tool> orderToolList = new ArrayList<Tool>();
			orderToolList = mergeAmountIntoDesireToolList( desireToolList, amountToolList );
			userSession.put(Constant.ORDER_TOOL, orderToolList);
			
			// Go to order screen
			returnString = "orderTool";
		}
		else
		{
			initialValue();
			suggForm = (Suggest)userSession.get( Constant.SUGG );
			desireToolList = (List<Tool>)userSession.get( Constant.ORDER_TOOL );
			addActionMessage( "กรุณาระบุจำนวนอุปกรณ์ที่ท่านต้องการ" );
			
			returnString = "tool";
		}
		
		return returnString;
	}
	
	@SuppressWarnings("unchecked")
	public String foodDetail() throws Exception
	{
		if( foodDetailIndex != null && foodDetailIndex.length() > 0 )
		{
			int index = Integer.parseInt(foodDetailIndex);
			selectedFood = ((List<Food>)userSession.get( Constant.ORDER_FOOD )).get(index);
		}
		return "foodDetail";
	}
	
//	private List<Food> mergeWithSizeAndPrice( List<Food> foodList, List<FoodProduct> foodProductList )
//	{
//		for ( int index = 0; index < foodList.size(); index++ )
//		{
//			Food food = foodList.get(index);
//			FoodProduct foodProduct = foodProductList.get(index);
//			
//			food.setSizeKg( foodProduct.getSizeKg() );
//			food.setPrice( foodProduct.getPrice() );
//			food.setPricePerKilogram( food.getPricePerKilogram() );
//			food.setFeedDayCount( foodProduct.getFeedDayCount() );
//			food.setPricePerDay( foodProduct.getPricePerDay() );
//		}
//		
//		return foodList;
//	}
	
	private List<Food> removeFoodDuplicate( List<Food> foodList )
	{
		List<Food> resultFoodList = new ArrayList<Food>();
		HashMap< Integer , Food> foodMap = new HashMap< Integer , Food>();
		for ( Food food : foodList )
		{
			foodMap.put( food.getId(), food);
		}
		
		resultFoodList = new ArrayList<Food>( foodMap.values() );
		
		return resultFoodList;
	}
	
	private Suggest MergeSuggFormIntoSugg( Suggest suggForm, Suggest sugg )
	{
		sugg.setGainWeightFlag(suggForm.isGainWeightFlag());
		sugg.setDietFlag(suggForm.isDietFlag());
		sugg.setIdealWeight(suggForm.getIdealWeight());
		sugg.setDryFoodType(suggForm.isDryFoodType());
		sugg.setWetFoodType(suggForm.isWetFoodType());
		sugg.setIdealWeightFoodNT(suggForm.isIdealWeightFoodNT());
		sugg.setJointBoneFoodNT(suggForm.isJointBoneFoodNT());
		sugg.setAllergyFoodNT(suggForm.isAllergyFoodNT());
		sugg.setAttractFoodNT(suggForm.isAttractFoodNT());
		sugg.setUrinaryFoodNT(suggForm.isUrinaryFoodNT());
		sugg.setDentalFoodNT(suggForm.isDentalFoodNT());
		sugg.setDigestiveFoodNT(suggForm.isDigestiveFoodNT());
		sugg.setSkinCoatFoodNT(suggForm.isSkinCoatFoodNT());
		sugg.setMuscleFoodNT(suggForm.isMuscleFoodNT());
		sugg.setBudget(suggForm.getBudget());
		sugg.setPeriodDay(suggForm.getPeriodDay());
		
		return sugg;
	}
	
	private ArrayList<Food> mergeAmountIntoDesireFoodList( List<Food> foodList, List<Food> amountFoodList )
	{		
		// Merge amount into desireFoodList
		for ( int index = 0; index < foodList.size(); index++ )
		{
			Food foodAmount = amountFoodList.get(index);
			if ( foodAmount.getAmount() > 0 )
			{
				foodList.get(index).setAmount( foodAmount.getAmount() );
			}
		}
		
		// Add only order Food
		ArrayList<Food> orderFoodList = new ArrayList<Food>();
		for ( Food food : foodList )
		{
			if ( food.getAmount() > 0 )
			{
				orderFoodList.add( food );
			}
		}
		
		return orderFoodList;
	}
	
	private ArrayList<Tool> mergeAmountIntoDesireToolList( List<Tool> toolList, List<Tool> amountToolList )
	{		
		// Merge amount into desireToolList
		for ( int index = 0; index < toolList.size(); index++ )
		{
			Tool toolAmount = amountToolList.get(index);
			if ( toolAmount.getAmount() > 0 )
			{
				toolList.get(index).setAmount( toolAmount.getAmount() );
			}
		}
		
		// Add only order Tool
		ArrayList<Tool> orderToolList = new ArrayList<Tool>();
		for ( Tool tool : toolList )
		{
			if ( tool.getAmount() > 0 )
			{
				orderToolList.add( tool );
			}
		}
		
		return orderToolList;
	}
	
	private String getDogSize( String breedSize, int year, int month ) throws Exception
	{
		String dogSize = "";
		
		if ( breedSize.equals("เล็กมาก") ){
			dogSize = Constant.SIZE_X_SMALL;
		}else if ( breedSize.equals("เล็ก") ){
			dogSize = Constant.SIZE_SMALL;
		}else if ( breedSize.equals("กลาง") ){
			dogSize = Constant.SIZE_MEDIUM;
		}else if ( breedSize.equals("ใหญ่") ){
			dogSize = Constant.SIZE_LARGE;
		}else if ( breedSize.equals("ใหญ่มาก") ){
			dogSize = Constant.SIZE_GIANT;
		}
		
		if( year == 0 )
		{
			DAOFactory daoFactory = new DAOFactory();
			daoFactory.beginConnection();
			SizeDAO sizeDAO = daoFactory.createSizeDAO();
			ArrayList<Size> allSize = sizeDAO.getAllSize();
			
			for ( Size size : allSize )
			{
				if ( dogSize.equals( size.getBreedSize() )
					&& month <= size.getEndAge() )
				{
					dogSize = size.getStandardSize();
					break;
				}
			}
		}
		
		return dogSize;
	}
	
	private String convertDogSizeToolSize( String dogSize )
	{
		String toolSize = "";
		
		if ( dogSize.equals( Constant.SIZE_X_SMALL ) ){
			toolSize = Constant.SIZE_SS;
		}else if ( dogSize.equals( Constant.SIZE_SMALL ) ){
			toolSize = Constant.SIZE_S;
		}else if ( dogSize.equals( Constant.SIZE_MEDIUM ) ){
			toolSize = Constant.SIZE_M;
		}else if ( dogSize.equals( Constant.SIZE_LARGE ) ){
			toolSize = Constant.SIZE_L;
		}else if ( dogSize.equals( Constant.SIZE_GIANT ) ){
			toolSize = Constant.SIZE_XL;
		}
		
		return toolSize;
	}
	
	private boolean isOrderSome( List<Food> foodList )
	{
		boolean orderSome = false;
		for ( Food food : foodList )
		{
			if ( food.getAmount() > 0 )
			{
				orderSome = true;
				break;
			}
		}
		
		return orderSome;
	}
	
	private boolean isOrderSomeT( List<Tool> toolList )
	{
		boolean orderSome = false;
		for ( Tool tool : toolList )
		{
			if ( tool.getAmount() > 0 )
			{
				orderSome = true;
				break;
			}
		}
		
		return orderSome;
	}
	
	private ArrayList<FoodFTN> getFoodFTNList( int foodId ) throws Exception
	{
		DAOFactory daoFactory = new DAOFactory();
		daoFactory.beginConnection();
		
		FoodDAO foodDAO = daoFactory.createFoodDAO();
		
		return foodDAO.getFoodFTNList( foodId );
	}
	
	private boolean isSpecifyFoodType( Suggest suggForm )
	{
		boolean isSpecifyFoodType = true;
		
		if ( ( suggForm.isWetFoodType() && suggForm.isDryFoodType() )
			|| ( !suggForm.isWetFoodType() && !suggForm.isDryFoodType() ) )
		{
			isSpecifyFoodType = false;
		}
		
		return isSpecifyFoodType;
	}
	
	/**
	 * 	private boolean idealWeightFoodNT; 	//ควบคุมน้ำหนัก 				FTN_TYPE_ID = 7
		private boolean jointBoneFoodNT; 	// บำรุงข้อต่อและกระดูก 			FTN_TYPE_ID = 2
		private boolean allergyFoodNT; 		// สำหรับผิวแพ้ง่าย 				FTN_TYPE_ID = 3
		private boolean attractFoodNT; 		// มีความน่ากินสูง 				FTN_TYPE_ID = 4
		private boolean urinaryFoodNT; 		//เพื่อสุขภาพที่ดีของระบบทางเดินปัสสาวะ	FTN_TYPE_ID = 5
		private boolean dentalFoodNT; 		// ลดการก่อหินปูนที่ฟัน			FTN_TYPE_ID = 6
		private boolean digestiveFoodNT; 	// โปรตีนมีคุณภาพ ย่อยและดูดซึมง่าย	FTN_TYPE_ID = 8
		private boolean skinCoatFoodNT; 	// เพื่อผิวหนังและขนสวยเงางาม		FTN_TYPE_ID = 9
		private boolean muscleFoodNT; 		// เสริมสร้างกล้ามเนื้อ			FTN_TYPE_ID = 10 
	 */
	private boolean isContainFoodFTNType( int foodId, Suggest suggForm ) throws Exception
	{
		boolean containFTN = false;
		
		DAOFactory daoFactory = new DAOFactory();
		daoFactory.beginConnection();
		
		FoodDAO foodDAO = daoFactory.createFoodDAO();
		ArrayList<Integer> foodFTNTypeList = foodDAO.getFoodFTNType( foodId );
		
		// Contain only one is OK!
		if ( suggForm.isIdealWeightFoodNT() && foodFTNTypeList.contains( 7 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isJointBoneFoodNT() && foodFTNTypeList.contains( 2 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isAllergyFoodNT() && foodFTNTypeList.contains( 3 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isAttractFoodNT() && foodFTNTypeList.contains( 4 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isUrinaryFoodNT() && foodFTNTypeList.contains( 5 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isDentalFoodNT() && foodFTNTypeList.contains( 6 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isDigestiveFoodNT() && foodFTNTypeList.contains( 8 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isSkinCoatFoodNT() && foodFTNTypeList.contains( 9 ) )
		{
			containFTN = true;
		}
		else if ( suggForm.isMuscleFoodNT() && foodFTNTypeList.contains( 10 ) )
		{
			containFTN = true;
		}
		
		return containFTN;
	}
	
	private boolean isSpecifyFoodFTN( Suggest suggForm )
	{
		boolean isSpecifyFTN = false;
		isSpecifyFTN = ( suggForm.isIdealWeightFoodNT()
				 || suggForm.isJointBoneFoodNT()
				 || suggForm.isAllergyFoodNT()
				 || suggForm.isAttractFoodNT()
				 || suggForm.isUrinaryFoodNT() 
				 || suggForm.isDentalFoodNT() 
				 || suggForm.isDigestiveFoodNT()
				 || suggForm.isSkinCoatFoodNT() 
				 || suggForm.isMuscleFoodNT() );
		
		return isSpecifyFTN;
	}
	
	private void showDetail() throws Exception
	{
		suggForm = (Suggest)userSession.get( Constant.SUGG );
		dog = (Dog)userSession.get( Constant.DOG );
		
		suggForm.setShowLastUpdated(true);
		suggForm.setShowDetail(true);
		
		suggForm.setAgeDisplay( CaninUtil.calAge( dog.getYearOfBirth(), dog.getMonthOfBirth() ) );
		suggForm.setWeight( dog.getDogWeight() );
		suggForm.setLifeSpan( CaninUtil.calLifeSpan( dog.getYearOfBirth(),
				dog.getMonthOfBirth(), dog.getPregnantWeeks(), 
				dog.getLactateWeeks(), dog.getBreedId() ) );
		suggForm.setBreedName( CaninUtil.getBreedNameByBreedId( dog.getBreedId() ) );
		
		sizes = CaninUtil.initializeDogSizes();
		String dogSize = CaninUtil.getBreedSizeByBreedId( dog.getBreedId() );
		suggForm.setBreedSize( sizes.get( dogSize ) );
		
		// Diet or Increase Weight, only when not puppy or pregnant/Lactate 
		if ( "วัยลูกสุนัข".equalsIgnoreCase(suggForm.getLifeSpan())
			|| ( "F".equalsIgnoreCase(dog.getSex()) && ( dog.getPregnantWeeks() != 0 || dog.getLactateWeeks() != 0 ) ) )
		{
			suggForm.setShowDiet( false );
		}
		else
		{
			suggForm.setShowDiet( true );
			
			// calc for diet/gain weight
			ArrayList<Integer> standardWeight = CaninUtil.getBreedStandardWeightByBreedId( dog.getBreedId() );
			suggForm.setStandardWeight( standardWeight.get(0) + " - " + standardWeight.get(1) );
			
			double percent = 0.0;
			if ( dog.getDogWeight() < standardWeight.get(0) )
			{
				// less weight need to gain weight
				suggForm.setCalcWeight( 1 );
				
				Double w = Double.parseDouble( String.valueOf( dog.getDogWeight() ) );
				Double minW = Double.parseDouble( String.valueOf( standardWeight.get(0) ) );
				percent = CaninUtil.round2decimal( ( (minW-w)/minW )*100 );
				suggForm.setPercentWeight( percent + "%" );
				
			}
			else if ( dog.getDogWeight() > standardWeight.get(1) )
			{
				// more weight need to diet
				suggForm.setCalcWeight( 2 );
				
				Double w = Double.parseDouble( String.valueOf( dog.getDogWeight() ) );
				Double maxW = Double.parseDouble( String.valueOf( standardWeight.get(1) ) );
				percent = CaninUtil.round2decimal( ( (w-maxW)/maxW )*100 );
				suggForm.setPercentWeight( percent + "%" );
			}
			else
			{
				// standard
				suggForm.setCalcWeight( 0 );
				suggForm.setPercentWeight( "" );
			}
		}
		
		userSession.put(Constant.DOG, dog);
		userSession.put(Constant.SUGG, suggForm);
	}
	
	/**
	 * Calculate period day 
	 */
	private int getRemainDayInPeriod( int pregnantWeeks, int lactateWeeks )
	{
		int periodDayCount = 0;
		if ( pregnantWeeks > 0 )
		{
			periodDayCount = Suggest.PREGNANT_DAY_COUNT - (pregnantWeeks*7);
			addActionMessage( "ระยะเวลาที่แนะนำ เพื่อให้อาหารมีเพียงพอสำหรับแม่สุนัข จนกว่าจะคลอดลูกคือ " + periodDayCount + " วัน" );
		}
		else if ( lactateWeeks > 0 )
		{
			periodDayCount = Suggest.LACTATE_DAY_COUNT - (lactateWeeks*7);
			addActionMessage( "ระยะเวลาที่แนะนำ เพื่อให้อาหารมีเพียงพอสำหรับแม่สุนัข จนกว่าลูกจะหย่านมคือ " + periodDayCount + " วัน" );
		}
		
		return periodDayCount;
	}
	
	private void initialValue() throws Exception
	{
		member = (Member)userSession.get( Constant.MEMBER );
		setDogNameList( CaninUtil.retrieveDogNameList( member.getMemberId() ) );
	}
	
	public Member getMember()
	{
		return member;
	}

	public void setMember(Member member)
	{
		this.member = member;
	}

	public Dog getDog()
	{
		return dog;
	}

	public void setDog(Dog dog)
	{
		this.dog = dog;
	}

	@Override
	public void setSession(Map<String, Object> userSession)
	{
		this.userSession = userSession;
	}

	public Map<String, String> getDogNameList()
	{
		return dogNameList;
	}

	public void setDogNameList(Map<String, String> dogNameList)
	{
		this.dogNameList = dogNameList;
	}

	public Suggest getSuggForm()
	{
		return suggForm;
	}

	public void setSuggForm(Suggest suggForm)
	{
		this.suggForm = suggForm;
	}

	public Suggest getSugg()
	{
		return sugg;
	}

	public void setSugg(Suggest sugg)
	{
		this.sugg = sugg;
	}

	public List<Food> getDesireFoodList()
	{
		return desireFoodList;
	}

	public void setDesireFoodList(List<Food> desireFoodList)
	{
		this.desireFoodList = desireFoodList;
	}

	public String getFoodDetailIndex() {
		return foodDetailIndex;
	}

	public void setFoodDetailIndex(String foodDetailIndex) {
		this.foodDetailIndex = foodDetailIndex;
	}

	public String getFoodDetailAmount() {
		return foodDetailAmount;
	}

	public void setFoodDetailAmount(String foodDetailAmount) {
		this.foodDetailAmount = foodDetailAmount;
	}

	public Food getSelectedFood() {
		return selectedFood;
	}

	public void setSelectedFood(Food selectedFood) {
		this.selectedFood = selectedFood;
	}

	public List<Tool> getDesireToolList()
	{
		return desireToolList;
	}

	public void setDesireToolList(List<Tool> desireToolList)
	{
		this.desireToolList = desireToolList;
	}
}
